package org.zh.sh.config;

import org.sqlite.SQLiteConfig;
import org.zh.sh.sv.proxy.*;
import org.zh.sh.util.CustomFormatter;
import org.zh.sh.util.Utils;
import org.zh.sh.util.http.PathBean;
import org.zh.sh.util.jdbc.TransactionBean;

import java.io.IOException;
import java.lang.invoke.MethodHandles;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import java.util.logging.ConsoleHandler;
import java.util.logging.FileHandler;
import java.util.logging.Level;
import java.util.logging.Logger;


public class GlobalStatic {
    private GlobalStatic(){}
    public static final Logger log = Logger.getLogger("java.RuntimeException");


    static {
        try{
            log.setUseParentHandlers(false);
            ConsoleHandler consoleHandler = new ConsoleHandler();
            consoleHandler.setLevel(Level.INFO);
            consoleHandler.setFormatter(new CustomFormatter());
            log.addHandler(consoleHandler);
            FileHandler fileHandler = new FileHandler("logs/app%u.log", 1073741824, 100, true);
            fileHandler.setLevel(Level.FINE);
            fileHandler.setFormatter(new CustomFormatter());
            log.addHandler(fileHandler);
            // SocketHandler socketHandler = new SocketHandler("127.0.0.1",9000);
            // socketHandler.setLevel(Level.WARNING);
            // socketHandler.setFormatter(new CustomFormatter());
            // logger.addHandler(socketHandler);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    public static final MethodHandles.Lookup lookup = MethodHandles.lookup();

    public static final ThreadLocal<Connection> localConn = new ThreadLocal<>();
    public static final Map<String, String> tablePris = new HashMap<>();
    public static final Properties env = new Properties();
    public static final String zhOpenTables = "ZHOpen.tables";
    public static final String zhOpenServerPort = "ZHOpen.server-port";
    public static final String zhOpenServerFixedThread = "ZHOpen.server-fixedThread";
    public static final String zhOpenServerBacklog = "ZHOpen.server-backlog";
    public static final String zhOpenDbType = "ZHOpen.dbType";
    public static final String userDir = "user.dir";
    public static final String classPath = "java.class.path";
    public static final Map<Integer, TransactionBean> hashTra = new HashMap<>();
    public static final Map<String, PathBean> vllCache = new HashMap<>();

    public static final Map<String, byte[]> staticFile = new HashMap<>();

    /*静态代理bean*/
    public static final ProxyAppRoleSV proxyAppRoleSV = new ProxyAppRoleSV();
    public static final ProxyAppUrlSV proxyAppUrlSV = new ProxyAppUrlSV();
    public static final ProxyAppUserSV proxyAppUserSV = new ProxyAppUserSV();
    public static final ProxyCurriculumSV proxyCurriculumSV = new ProxyCurriculumSV();
    public static final ProxyStudentCurriculumSV proxyStudentCurriculumSV = new ProxyStudentCurriculumSV();
    public static final ProxyStudentSV proxyStudentSV = new ProxyStudentSV();
    public static final ProxyTeacherSV proxyTeacherSV = new ProxyTeacherSV();
    /* 根据 appUserId 获取用户信息 包括用户权限缓存*/
    // public static final Cache<Long, Map<String, Object>> cache = Caffeine.newBuilder().maximumSize(100).expireAfterAccess(5, TimeUnit.HOURS).build();
    public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    public static final String SQlite_URL = "jdbc:sqlite:schools.db";
    public static final String mysql_URL = "jdbc:mysql://127.0.0.1:3306/Schools";

    public static String getPriKey(String tableName) {
        return tablePris.get(tableName);
    }

    public static void setLocalConn(int hashCode) {
        SQLiteConfig config = new SQLiteConfig();
        Connection conn;
        try {
            TransactionBean tb = hashTra.get(hashCode);
            if (tb.readOnly()) {
                config.setReadOnly(true);
                conn = DriverManager.getConnection(SQlite_URL, config.toProperties());
            } else {
                config.setReadOnly(false);
                config.setGetGeneratedKeys(true);
                config.setJournalMode(SQLiteConfig.JournalMode.WAL);
                conn = DriverManager.getConnection(SQlite_URL, config.toProperties());
                conn.setTransactionIsolation(tb.isolation());
                conn.setAutoCommit(false);
            }
            localConn.set(conn);
        } catch (SQLException e) {
            log.log(Level.SEVERE, "conn start false", e);
        }


    }

    public static void removeLocalConn(int hashCode) {
        TransactionBean tb = hashTra.get(hashCode);
        Connection conn = localConn.get();
        try {
            if (tb.readOnly()) {
                conn.close();
            } else {
                conn.commit();
                conn.close();
            }
        } catch (SQLException e) {
            try {
                conn.rollback();
                conn.close();
            } catch (SQLException ex) {
                log.log(Level.SEVERE, "conn rollback false", ex);
            }
            log.log(Level.SEVERE, "conn commit false", e);
        }
        localConn.remove();
    }

    public static void putHashTra(int hashCode, TransactionBean tb) {
        synchronized (hashTra) {
            hashTra.put(hashCode, tb);
        }
    }


    public static void print() {
       Utils.JSONPrint0(env,tablePris,hashTra,vllCache,staticFile.keySet());
    }
}
